#pragma once
#include <cstddef>
#include <cstdint>
#include "Logger.h"
namespace xncc {
using thread_id_type = long int;
struct LoggerConfig
{
    std::string logName;
    std::string logPath;
    std::size_t rotateSize;
    LOG_LEVEL   logLevel;
    bool        stdOut;  // 输出到控制台
    bool        nameFixed;
};

class LoggerFile
{
  public:
    explicit LoggerFile(const LoggerConfig& config);
    ~LoggerFile();

    LoggerFile(LoggerFile&&)                         = delete;
    LoggerFile(const LoggerFile&)                    = delete;
    auto operator=(LoggerFile&&) -> LoggerFile&      = delete;
    auto operator=(const LoggerFile&) -> LoggerFile& = delete;
    void writeLogMsg(const std::string& logdata);
    void writeBinary(const char* buffer, std::size_t len);
    void flush();

  private:
    auto getLogFileName() -> std::string;

    std::size_t        logDataLen_;
    std::string        logFileName_;
    FILE*              fp_;
    const LoggerConfig config_;
    const std::size_t  rotateSize_;  // MB
};

struct LogHeaderV1
{
    LogHeaderV1(LOG_LEVEL      level,
                thread_id_type pid,
                const char*    file,
                uint32_t       line,
                const char*    func,
                uint16_t       loggerId);
    LOG_LEVEL      level_;
    struct timeval tv_ = {};
    thread_id_type pid_;
    const char*    file_;
    uint32_t       line_;
    const char*    func_;
    uint16_t       loggerId_;

    void decode(std::string& str) const;

    static constexpr auto HEADER_LEN() -> uint32_t
    {
        return sizeof(LogHeaderV1);
    }
};

struct LogHeaderV2
{
    LogHeaderV2(LOG_LEVEL      level,
                thread_id_type pid,
                const char*    file,
                uint32_t       line,
                const char*    func,
                uint16_t       loggerId,
                int32_t        fmtId);
    LOG_LEVEL      level_;
    struct timeval tv_ = {};
    thread_id_type pid_;
    const char*    file_;
    uint32_t       line_;
    const char*    func_;
    uint16_t       loggerId_;
    int32_t        fmtId_;

    void decode(std::string& str) const;

    static constexpr auto HEADER_LEN() -> uint32_t
    {
        return sizeof(LogHeaderV2);
    }
};

struct LogHeaderV3
{
    LogHeaderV3(uint16_t loggerId, int32_t fmtId);
    uint16_t              loggerId_;
    int32_t               fmtId_;
    static constexpr auto HEADER_LEN() -> uint32_t
    {
        return sizeof(LogHeaderV3);
    }
};

struct LogHeaderV4
{
    explicit LogHeaderV4(uint16_t loggerId);
    uint16_t              loggerId_;
    static constexpr auto HEADER_LEN() -> uint32_t
    {
        return sizeof(LogHeaderV4);
    }
};

struct LogHeaderV5
{
    explicit LogHeaderV5(uint16_t loggerId);
    uint16_t              loggerId_;
    uint32_t              dataSize = 0;
    static constexpr auto HEADER_LEN() -> uint32_t
    {
        return sizeof(LogHeaderV5);
    }
};

struct LogHeaderV6
{
    LogHeaderV6(uint16_t loggerId, int32_t fmtId);
    uint16_t              loggerId_;
    int32_t               fmtId_;
    static constexpr auto HEADER_LEN() -> uint32_t
    {
        return sizeof(LogHeaderV6);
    }
};

enum class LOG_PARAM_TYPE : uint8_t
{
    NONE,
    HEADER_V1_TYPE,
    HEADER_V2_TYPE,
    HEADER_V3_TYPE,
    HEADER_V4_TYPE,
    HEADER_V5_TYPE,  // logbinary
    HEADER_V6_TYPE,  // logbinary
    SHORT_TYPE,
    UNSIGED_SHORT_TYPE,
    INT_TYPE,
    UNSIGNED_INT_TYPE,
    LONG_TYPE,
    UNSIGNED_LONG_TYPE,
    LONG_LONG_TYPE,
    UNSIGNED_LONG_LONG_TYPE,
    DOUBLE_TYPE,
    CHAR_PTR_TYPE,
    CONST_CHAR_PTR_TYPE,
    PTR_TYPE,
    LOG_OBJ_TYPE,
    HEX_FLAG_TYPE,
    DEC_FLAG_TYPE,
    OCT_FLAG_TYPE,
    BIN_FLAG_TYPE,
    OVER_FLAG_TYPE
};

}  // namespace xncc